# -*- coding: utf-8 -*-
'''
 @Author     : Capsion
 @email      : 373704015@qq.com
 @Date       : 2021_09_26
 @TIME       : 0:24
 @file_path  : "point_include_polygon"
 @Description: 带状地图索引点要素与面要素包含分析
'''

import arcpy
import sys
reload(sys)
sys.setdefaultencoding('utf8')


def get_coordinate(tar):
    """
    @Description 统一使用相同的坐标系处理输入的对象，减少异常

    - param tar :{any} 支持绝对路径的shp，或者layer元素对象，

    returns `{bool|spatialReference}` 返回坐标系类，

    """
    try:
        coordinate = None
        # layer类带dataSource属性，可以获取完整的数据路径
        tar_str = ""
        if hasattr(tar, 'dataSource'):
            tar_str = tar.dataSource
            coordinate = arcpy.Describe(tar_str).spatialReference

        # shp文件的话，读取同目录下的 .prj文件即可
        elif isinstance(tar, str) and tar.endswith('.shp'):
            tar_str = tar.replace('.shp', '.prj')
            if not arcpy.Exists(tar_str): return False

            coordinate = arcpy.SpatialReference(tar_str)

        arcpy.AddMessage("get_coordinate: " + str(coordinate))

        return coordinate
    except Exception:
        return False

# 全局变量初始化
input_point_shp = ""
input_polygon_shp = ""
polygon_field_str = "PageNumber"
new_field_str = "IN_PAGE"

# 无法使用参数形式，使用函数曲线救国
# 因为GetParameter、和GetParameterAsText经常无法正常赋值给参数，只能在运行中也使用
def input_point():
    """
    @Description 参数1，点图层
    """
    return arcpy.GetParameterAsText(0) or input_point_shp

def input_polygon():
    """
    @Description 参数2，面图层
    """
    return arcpy.GetParameterAsText(1) or input_polygon_shp

def polygon_field():
    """
    @Description 参数3，面图层属性字段
    """
    return arcpy.GetParameterAsText(2) or polygon_field_str

def new_field():
    """
    @Description 参数4，新的点字段，错放页面关联字段
    """
    return arcpy.GetParameterAsText(3) or new_field_str



def check_point_field(tar, field_name):
    """
    @Description 每次执行都先删除对应的字段，然后重新生成，保证后续函数能正常填入数据

    - param tar        :{str} 支持shp、个人|地理数据、要素等
    - param field_name :{str} 需要新建的字段

    """
    fields_list = arcpy.ListFields(tar)
    need_create = True
    for field in fields_list:
        if str(field.name) == str(field_name):
            need_create = False
            res = arcpy.DeleteField_management(tar, [field_name])
            break

    arcpy.AddField_management(
        tar,
        field_type="TEXT",
        field_name=field_name)

    arcpy.AddMessage("check_point_field: " + str(check_point_field))

def check_polygon_field(tar, field_name):
    """
    @Description 检查面图层是否有指定的字段

    - param tar        :{str} 支持shp、个人|地理数据、要素等
    - param field_name :{str} 需要关联到点图层的字段，

    """
    field_is_legal = False
    fields_list = arcpy.ListFields(tar)

    for field in fields_list:
        if field_name == field.name:
            field_is_legal = True
            break

    if not field_is_legal:
        arcpy.AddMessage("polygon field is not exist: " + str(tar))
        raise IOError

    arcpy.AddMessage("check_polygon_field: " + str(field_is_legal))

def main():
    i=0
    j=0
    with arcpy.da.UpdateCursor(input_point(), ["SHAPE@", new_field()], spatial_reference=input_point_coordinate) as point_rows:
        for row in point_rows:
            page_number = [] # 新字段内容容器
            point_shape = row[0]
            with arcpy.da.SearchCursor(input_polygon(), ["SHAPE@", polygon_field()], spatial_reference=input_point_coordinate) as polygon_rows:
                for eachPolygon in polygon_rows:
                    # 点几何和面几何进行判断，是否存在包含关系
                    if eachPolygon[0].contains(row[0]):
                        # 写入数据
                        page_number.append(str(eachPolygon[1]))
                    j+=1

            # 将 page_number 转换为字符串
            page_number = ','.join(page_number)
            row[1] = page_number
            # 更新数据
            point_rows.updateRow(row)
            i+=1

    arcpy.AddMessage('main success !! >>>> Please flush the cache <<<<<')


# 通过 MapDocument 判断当前是否在arcgis内被调用
is_run_with_ArcMap = False
try:
    mxd = arcpy.mapping.MapDocument(r"current")
    is_run_with_ArcMap = True
except Exception:
    arcpy.AddMessage('is_run_with_ArcMap: ' + str(is_run_with_ArcMap))
finally:
    is_run_with_ArcMap = False

# 普通py脚本调用，需要设置下面几个变量
if not is_run_with_ArcMap:
    # 示例
    from os import path
    work_dir = r'D:\CPS\MyProject\gis\learn\shp'

    # 点图层绝对路径
    input_point_shp = path.join(work_dir, r'贺江右岸.shp')

    # 面图层绝对路径
    input_polygon_shp = path.join(work_dir, r'A.shp')

    # 面图层的关联字段（需要面图层已存在的字段）
    polygon_field_str = "PageNumber"

    # 点图层的关联字段（新建）
    new_field_str = "IN_PAGE"


# 获取点图层坐标系，这里采用点图层的坐标系
input_point_coordinate = get_coordinate( arcpy.GetParameter(0) or input_point_shp )

# 判断字段是否真实有效
check_polygon_field(input_polygon(), polygon_field())

# 清空字段数据
check_point_field(input_point(), new_field())

# 断点
# arcpy.AddMessage(u'coordinate: ' + coordinate)

# 主函数
main()

